﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;

namespace STEditor.Classes.Tests
{
    [TestClass]
    public class STGameXamlLoaderTests
    {

        private DirectoryInfo _folder = null; 
        private const string TilesFolder = @"C:\Users\Rune\Documents\Visual Studio 2010\Projects\SilverTileApp\Assets";


        [TestInitialize]
        public void Initialize()
        {
            _folder = new DirectoryInfo(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()));
        }

        [TestCleanup]
        public void CleanUp()
        {
            if (_folder.Exists)
            {
                _folder.Delete(true);
            }
        }

        [TestMethod]
        public void Loaded_Load_Should_Take_Folder_As_Argument_And_Return_An_STGame_Object()
        {

            var saveGame = new STGame();

            new STGameXamlWriter().Save(saveGame, _folder.FullName);

            var loadGame = new STGameXamlLoader().Load(_folder.FullName);

            Assert.IsInstanceOfType(loadGame, typeof(STGame));

        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void Loader_Load_Should_Fail_For_Nonexisting_Folder()
        {

            var game = new STGameXamlLoader().Load(_folder.FullName);

        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void Loader_Load_Should_Fail_For_Folder_Missing_Tiles_Folder()
        {

            _folder.Create();
            // Missing tiles folder and gamedata.xaml
            var game = new STGameXamlLoader().Load(_folder.FullName);

        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void Loader_Load_Should_Fail_For_Folder_Missing_Gamedata_Xaml()
        {

            _folder.Create();

            // Create tiles folder
            new DirectoryInfo(Path.Combine(_folder.FullName, STGameXamlWriter.TilesFolderName)).Create();
            // Missing gamedata.xaml            
            var game = new STGameXamlLoader().Load(_folder.FullName);

        }

        [TestMethod]
        public void Loader_Load_Should_Return_An_STGame_Object_With_The_Same_Properties_As_The_Saved_One()
        {

            string tileName1 = "ZeldaTiles-0001-(0-0).png";
            string tileName2 = "ZeldaTiles-0002-(1-0).png";

            var saveGame = new STGame();
            var tile1 = saveGame.TileTypes.Add(Path.Combine(TilesFolder, tileName1));
            var tile2 = saveGame.TileTypes.Add(Path.Combine(TilesFolder, tileName2));

            var gameArea = new STGameArea { TileWidth = 32, TileHeight = 32, Width = 3, Height = 1, AreaName = "Area1" };
            gameArea.SetTile(0, 0, tile1);
            gameArea.SetTile(1, 0, tile2);
            // Tile at 2,0 should be empty
            saveGame.GameAreas.Add(gameArea);

            new STGameXamlWriter().Save(saveGame, _folder.FullName);

            var loadGame = new STGameXamlLoader().Load(_folder.FullName);

            Assert.AreEqual(saveGame.GameAreas.Count, loadGame.GameAreas.Count, "GameAreas was not read correctly");
            var loadedArea = loadGame.GameAreas.First();
            Assert.AreEqual(gameArea.AreaName, loadedArea.AreaName, "GameArea was not loaded with the right name");
            Assert.AreEqual(gameArea.Width, loadedArea.Width, "GameArea.Width was not loaded correctly");
            Assert.AreEqual(gameArea.Height, loadedArea.Height, "GameArea.Height was not loaded correctly");
            Assert.AreEqual(gameArea.TileWidth, loadedArea.TileWidth, "GameArea.TileWidth was not loaded correctly");
            Assert.AreEqual(gameArea.TileHeight, loadedArea.TileHeight, "GameArea.TileHeight was not loaded correctly");
            Assert.AreEqual(gameArea.Tiles.Count, loadedArea.Tiles.Count, "Tiles.Count was not set correctly");

            Assert.AreEqual(saveGame.TileTypes.Count, loadGame.TileTypes.Count, "TileTypes.Count was not set correctly");
                    
            var loadedTile1 = loadGame
                .TileTypes
                .Where(t => t.Source != null)
                .Where(t => Path.GetFileName(tile1.Source.LocalPath).Equals(Path.GetFileName(t.Source.LocalPath)))
                .Single();
            Assert.AreEqual(Path.GetFileName(tile1.Source.LocalPath), Path.GetFileName(loadedTile1.Source.LocalPath), "Source for tile1 was not loaded correctly");

            var gameTile1 = gameArea.Tiles.Where(t => t.Row == 0 && t.Column == 0).Single();
            var gameTile2 = gameArea.Tiles.Where(t => t.Row == 0 && t.Column == 1).Single();
            var gameTile3 = gameArea.Tiles.Where(t => t.Row == 0 && t.Column == 2).Single();

            Assert.IsNotInstanceOfType(gameTile1, typeof(EmptyTile), "Tile at 0,0 should not be empty");
            Assert.IsNotInstanceOfType(gameTile2, typeof(EmptyTile), "Tile at 1,0 should not be empty");
            Assert.IsInstanceOfType(gameTile3, typeof(EmptyTile), "Tile at 2,0 should be empty");

            Assert.AreSame(EmptyTile.EmptyImage, gameTile3.Image, "Image for tile at 2,0 should be the empty image");


        }

    }
}
